package moTSP;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;

public class TspGenotype {
    
    private List<Integer> visitingOrder;
    private Random rand = new Random();
    
    /**
     * Tworzy losowy genotyp dla podanej jako argument ilości miast
     * @param numOfCities
     */
    public TspGenotype(int numOfCities) {
        
        visitingOrder = new ArrayList<Integer>(numOfCities);
        
        List<Integer> cities = new ArrayList<Integer>(numOfCities);
        for (int cityNum = 0; cityNum < numOfCities; cityNum++) {
            cities.add(cityNum);
        }
        
        for (int cityNum = 0; cityNum < numOfCities; cityNum++) {
            int city = cities.remove(rand.nextInt(cities.size()));
            visitingOrder.add(city);
        }
            
    }
    
    public TspGenotype(TspGenotype tspGenotype) {
        this.visitingOrder = new ArrayList<Integer>(tspGenotype.getVisitingOrder());
    }
    
    List<Integer> getVisitingOrder() {
        return visitingOrder;
    }

    public void setVisitingOrder(List<Integer> visitingOrder) {
        this.visitingOrder = visitingOrder;
    }

    public int getRandomCityNum() {
        return visitingOrder.get(rand.nextInt(visitingOrder.size()));
    }

    public int getRandomCityNumOtherThan(int firstCity) {
        while (true) {
            int rand = getRandomCityNum();
            if (rand != firstCity) {
                return rand;
            }
        }
    }

    public int getNextCity(int firstCity) {
        
        int firstCityIndex = visitingOrder.indexOf(firstCity);
        return visitingOrder.get(firstCityIndex + 1);
    }

    public boolean cityIsLast(int firstCity) {
        
        if (visitingOrder.indexOf(firstCity) == visitingOrder.size() - 1) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * Inverse the section from the next city of city <i>firstCity</i> to the city <i>secondCity</i>
     * @param firstCity
     * @param secondCity
     */
    public void inverse(int firstCity, int secondCity) {
        int firstCityIndex = visitingOrder.indexOf(firstCity);
        int secondCityIndex = visitingOrder.indexOf(secondCity);
        
        if (firstCityIndex > secondCityIndex) {
            int temp = firstCityIndex;
            firstCityIndex = secondCityIndex;
            secondCityIndex = temp;
        }
        Collections.reverse(visitingOrder.subList(firstCityIndex+1, secondCityIndex));
    }

}
